<template>
	<div class="drawer-layout" v-loading="loading">
		<!-- Header -->
		<div class="drawer-header">{{ form.id ? "编辑用户" : "新增用户" }}</div>

		<!-- Body -->
		<div class="drawer-body">
			<el-alert v-if="form.id === 0" title="登录密码默认手机号码后8位" type="warning" show-icon
			          style="margin-bottom: 15px;"/>
			<el-form ref="formRef" :model="form" label-width="80px">
				<el-form-item label="头像" prop="avatar">
					<el-upload class="avatar-uploader" :show-file-list="false" :before-upload="beforeAvatarUpload">
						<img v-if="form.avatar" :src="formAvatar(form.avatar)" class="avatar" alt="">
						<i v-else class="el-icon-plus avatar-uploader-icon"></i>
					</el-upload>
				</el-form-item>
				<el-form-item label="用户昵称" prop="nickname" :rules="{ required: true, message: '请输入用户昵称' }">
					<el-input v-model="form.nickname" placeholder="请输入用户昵称"/>
				</el-form-item>
				<el-form-item label="邮箱地址" prop="email" :rules="{ required: true, message: '请输入邮箱地址' }">
					<el-input v-model="form.email" placeholder="请输入邮箱地址"/>
				</el-form-item>
				<el-form-item label="真实姓名" prop="realname" :rules="{ required: true, message: '请输入真实姓名' }">
					<el-input v-model="form.realname" placeholder="请输入真实姓名"/>
				</el-form-item>
				<el-form-item label="手机号码" prop="mobile" :rules="{ required: true, message: '请输入手机号码' }">
					<el-input v-model="form.mobile" placeholder="请输入手机号码"/>
				</el-form-item>
				<el-form-item label="身份证号" prop="identity" :rules="{ required: true, message: '请输入身份证号' }">
					<el-input v-model="form.identity" placeholder="请输入身份证号"/>
				</el-form-item>
				<el-form-item label="性别" prop="gender">
					<el-radio-group v-model="form.gender">
						<el-radio
							v-for="state in filter.gender"
							:key="state.key"
							:value="state.key"
						>
							{{ state.label }}
						</el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item label="个性签名">
					<el-input type="textarea" rows="3" v-model="form.description" placeholder="请输入个性签名"/>
				</el-form-item>
				<el-form-item label="角色" prop="roles">
					<el-select
						v-model="form.roles"
						multiple
						filterable
						placeholder="请选择角色"
						style="width: 100%;"
					>
						<el-option
							v-for="role in roles"
							:key="role.id"
							:label="role.name"
							:value="role.id"
						/>
					</el-select>
				</el-form-item>
				<el-form-item label="状态" prop="state">
					<el-radio-group v-model="form.state">
						<el-radio
							v-for="state in filter.state"
							:key="state.key"
							:value="state.key"
						>
							{{ state.label }}
						</el-radio>
					</el-radio-group>
				</el-form-item>
			</el-form>
		</div>
		<!-- Footer -->
		<div class="drawer-footer">
			<el-button @click="onCancel">取消</el-button>
			<el-button type="primary" @click="onSubmit" :loading="loading">确认</el-button>
		</div>
	</div>
</template>

<script setup lang="ts">
import {reactive, ref, watch} from "vue";
import {
	createUserApi,
	getUserDetailApi,
	getUserFilterApi,
	getUserRoleApi,
	updateUserApi
} from "@/api/modules/setting.ts";
import type {FilterModel} from "@/models/filterModel.ts";
import {ElMessage} from "element-plus";
import {randomNick, formAvatar} from '@/utils/user.ts';
import {RoleModel} from "@/models/settingModel.ts";
import {fileUpload} from "@/utils/upload.ts";

const loading = ref(false);
const props = defineProps<{ modelValue: boolean; userID?: number }>();
const emit = defineEmits(["update:modelValue", "success"]);
const onCancel = () => {
	emit("update:modelValue", false);
};

// 表单
function getDefaultForm(userID = 0) {
	return {
		id: userID,
		nickname: "",
		avatar: "/img/logo.png" as string | Blob,
		email: "",
		realname: "",
		mobile: "",
		identity: "",
		gender: "hide",
		description: "",
		state: "normal",
		roles: [] as number[],
	};
}

const form = reactive(getDefaultForm(props.userID ?? 0));
const roles = ref<RoleModel[]>([]);

function resetForm(userID = 0) {
	Object.assign(form, getDefaultForm(userID));
	form.nickname = randomNick();
}

const filter = reactive<FilterModel>({
	gender: [],
	state: [],
});

const loadFilters = async () => {
	const filterData = await getUserFilterApi();
	filter.gender = Object.entries(filterData.data.data.gender || {}).map(
		([key, label]) => ({key, label})
	);
	filter.state = Object.entries(filterData.data.data.state || {}).map(
		([key, label]) => ({key, label})
	);
};


const loadDetail = async (id: number) => {
	const userData = await getUserDetailApi({id: id});
	Object.assign(form, userData.data.data);
}
const loadRoles = async () => {
	const roleData = await getUserRoleApi({});
	roles.value = roleData.data.data;
}

watch(
	() => props.modelValue,
	async (val) => {
		if (val) {
			loading.value = true;
			resetForm(props.userID ?? 0);
			try {
				await loadFilters();
				await loadRoles();
				if (form.id > 0) {
					await loadDetail(form.id);
				}
			} catch (error) {
				emit("update:modelValue", false);
				console.error(error);
			} finally {
				loading.value = false;
			}
		}
	},
	{immediate: true}
);

const beforeAvatarUpload = (file: File) => {
	const result = fileUpload(file);
	result.then(blob => {
		form.avatar = blob;
	}).catch(error => {
		ElMessage.error(error);
	});
	return false;
};

// 提交
const submitting = ref(false);
const onSubmit = async () => {
	if (submitting.value) return
	submitting.value = true;
	try {
		if (form.id > 0) {
			const updateData = await updateUserApi(form);
			ElMessage.success(updateData.message);
		} else {
			const createData = await createUserApi(form);
			ElMessage.success(createData.message);
		}
		emit("success", {...form});
		emit("update:modelValue", false);
	} catch (error) {
		console.log(error);
	} finally {
		submitting.value = false;
	}
};
</script>

<style scoped>
.drawer-layout {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.drawer-header {
	flex: 0 0 60px;
	padding: 16px 20px;
	font-size: 18px;
	font-weight: 600;
	border-bottom: 1px solid #ebeef5;
}

.drawer-body {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 20px;
}

.drawer-footer {
	flex: 0 0 64px;
	padding: 12px 20px;
	border-top: 1px solid #ebeef5;
	background: #fff;
	text-align: right;
}

.drawer-footer .el-button + .el-button {
	margin-left: 12px;
}

.avatar-uploader ::v-deep(.el-upload) {
	width: 120px;
	height: 120px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 1px dashed #d9d9d9;
	border-radius: 50%;
	cursor: pointer;
	overflow: hidden;
}

.avatar-uploader ::v-deep(.el-upload) .avatar-uploader-icon {
	font-size: 28px;
	color: #8c939d;
}

.avatar-uploader ::v-deep(.el-upload) .avatar {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
</style>
